package com.advertisementsystem.Servie.Impl;

import com.advertisementsystem.Dto.RoleDTO;
import com.advertisementsystem.Exception.BusinessException;
import com.advertisementsystem.Mapper.PermissionMapper;
import com.advertisementsystem.Mapper.RoleMapper;
import com.advertisementsystem.Mapper.RolePermissionMapper;
import com.advertisementsystem.Servie.RoleService;
import com.advertisementsystem.entity.Permission;
import com.advertisementsystem.entity.Role;
import com.advertisementsystem.entity.RolePermission;

import com.advertisementsystem.entity.UserRole;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Override
    public Page<Role> getRoleList(Integer pageNum, Integer pageSize, String name, String code, Integer status) {
        Page<Role> page = new Page<>(pageNum, pageSize);
        return roleMapper.selectRolesByCondition(page, name, code, status);
    }

    @Override
    public List<Role> getAllRoles() {
        return roleMapper.selectList(null);
    }

    @Override
    public Role getRoleById(Long id) {
        return roleMapper.selectById(id);
    }

    @Override
    @Transactional
    public void addRole(RoleDTO roleDTO) {
        // 检查角色编码唯一性
        checkRoleCodeExists(roleDTO.getCode(), null);

        // 创建角色
        Role role = new Role();
        BeanUtils.copyProperties(roleDTO, role);

        // 设置默认值
        LocalDateTime now = LocalDateTime.now();
        role.setCreatedTime(now);
        role.setUpdatedTime(now);
        if (role.getStatus() == null) {
            role.setStatus(1);
        }

        // 插入角色
        roleMapper.insert(role);

        // 如果有权限列表，分配权限
        if (roleDTO.getPermissionIds() != null && !roleDTO.getPermissionIds().isEmpty()) {
            assignPermissions(role.getId(), roleDTO.getPermissionIds());
        }
    }

    @Override
    @Transactional
    public void updateRole(Long id, RoleDTO roleDTO) {
        // 检查角色是否存在
        Role existingRole = roleMapper.selectById(id);
        if (existingRole == null) {
            throw new BusinessException("角色不存在");
        }

        // 如果是系统管理员角色，禁止修改编码
        if ("ADMIN".equals(existingRole.getCode()) && !existingRole.getCode().equals(roleDTO.getCode())) {
            throw new BusinessException("不能修改系统管理员角色的编码");
        }

        // 检查角色编码唯一性（排除自身）
        checkRoleCodeExists(roleDTO.getCode(), id);

        // 更新角色
        Role role = new Role();
        BeanUtils.copyProperties(roleDTO, role);
        role.setId(id);
        role.setUpdatedTime(LocalDateTime.now());
        role.setCreatedTime(existingRole.getCreatedTime());

        // 更新角色信息
        roleMapper.updateById(role);

        // 如果有权限列表，重新分配权限
        if (roleDTO.getPermissionIds() != null) {
            assignPermissions(id, roleDTO.getPermissionIds());
        }
    }

    @Override
    @Transactional
    public void deleteRole(Long id) {
        // 检查角色是否存在
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 不能删除系统管理员角色
        if ("ADMIN".equals(role.getCode())) {
            throw new BusinessException("不能删除系统管理员角色");
        }

        // 删除角色权限关联
        rolePermissionMapper.deleteByRoleId(id);

        // 删除角色
        roleMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void updateRoleStatus(Long id, Integer status) {
        // 检查角色是否存在
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 不能禁用系统管理员角色
        if ("ADMIN".equals(role.getCode()) && status == 0) {
            throw new BusinessException("不能禁用系统管理员角色");
        }

        // 更新状态
        Role updateRole = new Role();
        updateRole.setId(id);
        updateRole.setStatus(status);
        updateRole.setUpdatedTime(LocalDateTime.now());

        roleMapper.updateById(updateRole);
    }

    @Override
    @Transactional
    public void assignPermissions(Long roleId, List<Long> permissionIds) {
        // 检查角色是否存在
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 删除原有权限
        rolePermissionMapper.deleteByRoleId(roleId);

        // 如果没有权限，直接返回
        if (permissionIds == null || permissionIds.isEmpty()) {
            return;
        }

        // 创建新权限关系
        List<RolePermission> rolePermissions = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();

        for (Long permissionId : permissionIds) {
            RolePermission rp = new RolePermission();
            rp.setRoleId(roleId);
            rp.setPermissionId(permissionId);
            rp.setCreatedTime(now);
            rolePermissions.add(rp);
        }

        // 批量插入
        rolePermissionMapper.insertBatch(rolePermissions);
    }

    @Override
    public List<Permission> getRolePermissions(Long roleId) {
        // 检查角色是否存在
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 获取角色的权限
        return permissionMapper.selectPermissionsByRoleId(roleId);
    }

    @Override
    public List<Role> getRolesByUserId(Long id) {
        LambdaQueryWrapper<UserRole> query = new LambdaQueryWrapper<>();
        query.eq(UserRole::getUserId, id);
        return roleMapper.selectRolesByUserId(id);
    }

    /**
     * 检查角色编码是否已存在
     */
    private void checkRoleCodeExists(String code, Long excludeId) {
        if (!StringUtils.hasText(code)) {
            return;
        }

        LambdaQueryWrapper<Role> query = new LambdaQueryWrapper<>();
        query.eq(Role::getCode, code);
        if (excludeId != null) {
            query.ne(Role::getId, excludeId);
        }

        Integer count = Math.toIntExact(roleMapper.selectCount(query));
        if (count > 0) {
            throw new BusinessException("角色编码已存在");
        }
    }
}